package com.decent.manager.config.security.entrypoint;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.decent.common.bo.MessageBean;
import com.decent.common.enums.ErrorCodeEnum;
import com.decent.manager.system.cache.ResourceCache;
import com.decent.manager.system.util.CommonServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;

/**
 * 未认证用户访问须授权资源端点
 *
 * @author 张子旭
 * @date 2022/1/20
 */
@Slf4j
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable {
    private static final long serialVersionUID = -565414518733397920L;
    @Resource
    private ResourceCache<Set<String>> resourceCache;

    /**
     * 访问未经授权的接口时执行此方法，未经授权的接口包含系统中存在和不存在的接口，分别处理
     */
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
        String requestUri = request.getRequestURI();
        requestUri = StrUtil.removePrefix(requestUri, request.getContextPath());
        response.setStatus(HttpServletResponse.SC_OK);
        // 检查redis中RESOURCE缓存是否为空
        Collection<String> urlCollections = resourceCache.get(ResourceCache.URL_CACHE);
        if (ObjectUtil.isEmpty(urlCollections)) {
            log.error("获取缓存的Resource Url为空，requestUri={}", requestUri);
            CommonServletUtil.writeJsonToResponse(response, new MessageBean(ErrorCodeEnum.NO, "资源路径获取失败"));
            return;
        }

        // 判断缓存的url中是否有当前请求的uri
        if (!urlCollections.contains(requestUri)) {
            log.error("当前请求的uri不存在，requestUri={}", requestUri);
            CommonServletUtil.writeJsonToResponse(response, new MessageBean(ErrorCodeEnum.NO, "请求地址[" + requestUri + "]不存在，请检查请求地址是否正确"));
            return;
        }
        // 响应给前端无权限访问本接口（没有携带token）
        log.error("没有权限访问该资源，requestUri={}", requestUri);
        CommonServletUtil.writeJsonToResponse(response, new MessageBean(ErrorCodeEnum.UNAUTHORIZED));
    }
}
